package com.wct.db;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.types.ObjectId;

import com.sequoiadb.base.DBCollection;
import com.sequoiadb.base.DBCursor;
import com.sequoiadb.base.Sequoiadb;
import com.sequoiadb.base.SequoiadbDatasource;
import com.sequoiadb.exception.BaseException;
import com.wct.define.Constant;
import com.wct.struct.GPSPacket;
import com.wct.struct.SyscfgPacket2;
import com.wct.util.GPSUtil;

public class DbUtils {
	private final Logger logger = LogManager.getLogger(DbUtils.class);
	private SequoiadbDatasource ds;

	public SequoiadbDatasource getDs() {
		return ds;
	}

	public void setDs(SequoiadbDatasource ds) {
		this.ds = ds;
	}
	
	public BSONObject getDevice(String deviceid){
		try {
	        Sequoiadb db = ds.getConnection();
	        DBCollection cl =  db.getCollectionSpace(Constant.CollectionSpace).getCollection(Constant.tablenames.Device);;
	        DBCursor cursor = cl.query("{" + Constant.Device.ID + ":'" + deviceid + "'}", null, null, null);

	        BSONObject info = null;
	        while (cursor.hasNext()) {
	        	info = cursor.getNext();
	        	break;
	        }
	        
	        ds.close(db);
	        
	        return info;
        } catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
    		
	        return null;
        } 
	}
	
	public void updateDeviceinfo(SyscfgPacket2 packet){
		try {
			Sequoiadb db = ds.getConnection();
			DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace).getCollection(Constant.tablenames.Device);
	
			cl.update("{'" + Constant.Device.ID + "':'" + packet.DeviceSN.get() + "'}", 
				"{$set:{'" + Constant.Device.powerStatus + "':" + (packet.Data.bDevice.get()==1?"true":"false") +
				",'" + Constant.Device.voiceStatus + "':" + (packet.Data.bMusic.get()==1?"true":"false") +
				",'" + Constant.Device.mainNumber + "':'" + packet.Data.CtrlNumber.get() +
				"','" + Constant.Device.backupNumber1 + "':'" + packet.Data.UrgentNumber.get() +
				"','" + Constant.Device.mode + "':" + packet.Data.Mode.get() +
				",'" + Constant.Device.interval + "':" + packet.Data.InterVal.get() + "}}", null);
	        			
			ds.close(db);
		} catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
        }
	}
	
	public void updateDevicePower(String deviceId, Integer power){
		try {
			Sequoiadb db = ds.getConnection();
			DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace).getCollection(Constant.tablenames.Device);
	
			cl.update("{'" + Constant.Device.ID + "':'" + deviceId + "'}", 
				"{$set:{'" + Constant.Device.power + "':" + power + "}}", null);
	        			
			ds.close(db);
		} catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
        }
	}
	
	public void appendGPSRecord(GPSPacket packet, Double x, Double y){
		try {
			Sequoiadb db = ds.getConnection();
			DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace).getCollection(Constant.tablenames.Record);
			BSONObject obj = new BasicBSONObject();
			obj.put(Constant.Record.ID, new ObjectId());

			obj.put(Constant.Record.x, x);
			
			obj.put(Constant.Record.y, y);
			obj.put(Constant.Record.time, new Date().getTime());
			obj.put(Constant.Record.deviceid, packet.DeviceSN.get() + "");
			obj.put(Constant.Record.speed, packet.Data.Speed.get());
			obj.put(Constant.Record.angle, packet.Data.Direct.get());
			obj.put(Constant.Record.positionStatus, true);
			obj.put(Constant.Record.heightGroud, packet.Data.heightGgroud.get());
			obj.put(Constant.Record.heightSea, packet.Data.HeightSea.get());
			cl.insert(obj);
			ds.close();
		} catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
        } 
	}
	
	public java.util.List<BSONObject> getFences(String deviceId){
		try {
	        Sequoiadb db = ds.getConnection();
	        DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace)
	            .getCollection(Constant.tablenames.Fence);
	        DBCursor cursor = cl.query(
	            "{'" + Constant.Fence.deviceid + "':'" + deviceId + "'}", null, null,
	            null);
	        List<BSONObject> recordList = new LinkedList<BSONObject>();
	        while (cursor.hasNext()) {
	        	BSONObject bsonObject = cursor.getNext();
	        	recordList.add(bsonObject);
	        }
	        ds.close(db);
	        return recordList;
        } catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
    		return null;
        }
	}
	
	public void updateFence(String fenceId, Boolean infence){
		try {
	        Sequoiadb db = ds.getConnection();
	        DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace)
	            .getCollection(Constant.tablenames.Fence);
	        cl.update("{'" + Constant.Fence.ID + "':'" + fenceId + "'}", "{$set:{'" + Constant.Fence.infence + "':" + infence.toString() + "}}", null);
        } catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
        }
	}
	
	public void updateDeviceOnlineStatus(String deviceId, boolean online){
		try {
			Sequoiadb db = ds.getConnection();
			DBCollection cl = db.getCollectionSpace(Constant.CollectionSpace).getCollection(Constant.tablenames.Device);
	
			cl.update("{'" + Constant.Device.ID + "':'" + deviceId + "'}", 
				"{$set:{'" + Constant.Device.online + "':" + online + "}}", null);
	        			
			ds.close(db);
		} catch (BaseException | InterruptedException e) {
        	StringWriter sw = new StringWriter();
    		PrintWriter pw = new PrintWriter(sw);
    		e.printStackTrace(pw);

    		logger.error(sw.toString());
        }
	}
	
}
